#include "head.h"
// 1.0
//int transFile(int netfd){
//    char filename[] = "file1";
//    send(netfd,filename,5,0); //先发文件名
//    int fd = open(filename,O_RDWR);
//    char buf[1000] = {0};
//    ssize_t ret= read(fd,buf,sizeof(buf));//读磁盘文件
//    send(netfd,buf,ret,0);//如何确定要发送内容的长度，根据read的返回值
//    return 0;
//}
// 2.0
//typedef struct train_s {
//    int length; // 4字节的长度
//    char data[1000]; 
//    // 1000是车厢的上限，不是实际长度
//    // char不代表字符，只是为了方便控制内存大小
//} train_t;
//int transFile(int netfd){
//    train_t train;
//    char filename[] = "file1";
//    // 把发送的内容填充进小火车
//    train.length = strlen(filename);//填充火车头
//    memcpy(train.data,filename,train.length);//填充车厢
//    // 发送小火车
//    send(netfd,&train,sizeof(train.length)+train.length,0);
//    //根据实际车厢的长度去发送
//    int fd = open(filename,O_RDWR);
//    char buf[1000] = {0};
//    ssize_t ret= read(fd,buf,sizeof(buf));//读磁盘文件
//    train.length = ret;
//    memcpy(train.data,buf,train.length);
//    send(netfd,&train,sizeof(train.length)+train.length,0);
//    return 0;
//}
//3.0
//typedef struct train_s {
//    int length; // 4字节的长度
//    char data[1000]; 
//} train_t;
//int transFile(int netfd){
//    train_t train;
//    char filename[] = "file1";
//    // 把发送的内容填充进小火车
//    train.length = strlen(filename);//填充火车头
//    memcpy(train.data,filename,train.length);//填充车厢
//    // 发送小火车
//    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//    //根据实际车厢的长度去发送
//    int fd = open(filename,O_RDWR);
//    char buf[1000] = {0};
//    while(1){
//        ssize_t ret= read(fd,buf,sizeof(buf));//读磁盘文件
//        train.length = ret;
//        memcpy(train.data,buf,train.length);
//        send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//        // 即时ret是0，也要发一个空的火车过去，再退出
//        if(ret == 0){
//            break;
//        }
//    }
//    close(fd);
//    return 0;
//}
//4.0
//typedef struct train_s {
//    int length; // 4字节的长度
//    char data[1000]; 
//} train_t;
//int transFile(int netfd){
//    train_t train;
//    char filename[] = "file1";
//    // 把发送的内容填充进小火车
//    train.length = strlen(filename);//填充火车头
//    memcpy(train.data,filename,train.length);//填充车厢
//    // 发送小火车
//    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//    //根据实际车厢的长度去发送
//    int fd = open(filename,O_RDWR);
//    // 发送文件的长度
//    struct stat statbuf;
//    fstat(fd,&statbuf);
//    train.length = sizeof(off_t);
//    memcpy(train.data,&statbuf.st_size,train.length);//把文件的长度放入小火车
//    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//
//    char buf[1000] = {0};
//    while(1){
//        ssize_t ret= read(fd,buf,sizeof(buf));//读磁盘文件
//        train.length = ret;
//        memcpy(train.data,buf,train.length);
//        send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//        // 即时ret是0，也要发一个空的火车过去，再退出
//        if(ret == 0){
//            break;
//        }
//    }
//    close(fd);
//    return 0;
//}
//4.1 零拷贝
//typedef struct train_s {
//    int length; // 4字节的长度
//    char data[1000]; 
//} train_t;
//int transFile(int netfd){
//    train_t train;
//    char filename[] = "file1";
//    // 把发送的内容填充进小火车
//    train.length = strlen(filename);//填充火车头
//    memcpy(train.data,filename,train.length);//填充车厢
//    // 发送小火车
//    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//    //根据实际车厢的长度去发送
//    int fd = open(filename,O_RDWR);
//    // 发送文件的长度
//    struct stat statbuf;
//    fstat(fd,&statbuf);
//    train.length = sizeof(off_t);
//    memcpy(train.data,&statbuf.st_size,train.length);//把文件的长度放入小火车
//    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
//    // 建立映射区
//    char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
//    // 整个文件的内容都已经加载到内存里面，接下来就一个一个火车发过去
//    off_t cursize = 0; // 记录已经发送的文件大小
//    while(1){
//        if(cursize >= statbuf.st_size){
//            break;
//        }
//        //先准备好小火车的长度
//        if(statbuf.st_size-cursize >= 1000){
//            train.length = 1000;
//        }
//        else{
//            train.length = statbuf.st_size-cursize;
//        }
//        // 发小火车 （车头和车厢分开发）
//        send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);//用户态的火车头
//        send(netfd,p+cursize,train.length,MSG_NOSIGNAL);//内核态的火车车厢
//        cursize += train.length;
//    }
//    // 最后发一个空的火车头
//    train.length = 0;
//    send(netfd,&train.length,sizeof(train.length),MSG_NOSIGNAL);
//    munmap(p,statbuf.st_size);
//    close(fd);
//    return 0;
//}
//5.0 一次性全发过去
typedef struct train_s {
    int length; // 4字节的长度
    char data[1000]; 
} train_t;
int transFile(int netfd){
    train_t train;
    char filename[] = "file1";
    // 把发送的内容填充进小火车
    train.length = strlen(filename);//填充火车头
    memcpy(train.data,filename,train.length);//填充车厢
    // 发送小火车
    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
    //根据实际车厢的长度去发送
    int fd = open(filename,O_RDWR);
    // 发送文件的长度
    struct stat statbuf;
    fstat(fd,&statbuf);
    train.length = sizeof(off_t);
    memcpy(train.data,&statbuf.st_size,train.length);//把文件的长度放入小火车
    send(netfd,&train,sizeof(train.length)+train.length,MSG_NOSIGNAL);
   // // 建立映射区
   // char *p = (char *)mmap(NULL,statbuf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
   // // 整个文件的内容都已经加载到内存里面，接下来就一个整体发过去
   // send(netfd,p,statbuf.st_size,MSG_NOSIGNAL);
   // munmap(p,statbuf.st_size);
    sendfile(netfd,fd,NULL,statbuf.st_size);
    close(fd);
    return 0;
}
